package yehang.shared.entity;

import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.lang.Nullable;

import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author CJ (power4j@outlook.com)
 * @date 2021/3/31
 * @since 1.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("分页返回结果")
public class PageableResponse<T> {

    private final static long DEFAULT_PAGE_NUM = 1L;

    private final static long DEFAULT_PAGE_SIZE = 10L;

    private final static long DEFAULT_TOTAL_ELEMENTS = 10L;

    @Nullable
    private List<T> result;

    @Nullable
    @ApiModelProperty(value = "当前页码", notes = "当前请求页码")
    private long page = DEFAULT_PAGE_NUM;

    @Nullable
    @ApiModelProperty(value = "每页记录数", notes = "每页记录数")
    private long pageSize = DEFAULT_PAGE_SIZE;

    @Nullable
    @ApiModelProperty(value = "总记录数", notes = "所有记录数")
    private long total = DEFAULT_TOTAL_ELEMENTS;

    /**
     * 转换业务数据(elements)的数据类型。典型使用场景是 PO -> DTO
     *
     * @param converter 转换函数
     * @param <U>       新的数据类型
     * @return 返回新的PageableResponse对象
     */
    public <U> PageableResponse<U> map(Function<? super T, ? extends U> converter) {
        if (Objects.isNull(result)) {
            return new PageableResponse<>(null, page, pageSize, total);
        } else {
            List<U> list = result.stream().map(converter).collect(Collectors.toList());
            return new PageableResponse<>(list, page, pageSize, total);
        }
    }

    public static <E> PageableResponse<E> create(PageInfo<E> pageInfo) {
        PageableResponse pageableResponse = new PageableResponse();
        pageableResponse.setPage(pageInfo.getPageNum());
        pageableResponse.setPageSize(pageInfo.getPageSize());
        pageableResponse.setTotal(pageInfo.getTotal());
        pageableResponse.setResult(pageInfo.getList());

        return pageableResponse;
    }
}
